package com.xuecheng.content.service.impl;

import cn.hutool.core.lang.UUID;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xuecheng.commons.constants.CommonConstants;
import com.xuecheng.commons.constants.CourseConstants;
import com.xuecheng.commons.enums.ErrorCode;
import com.xuecheng.commons.model.dto.CourseAuditDto;
import com.xuecheng.commons.model.dto.CourseBaseDto;
import com.xuecheng.commons.model.dto.CourseDto;
import com.xuecheng.commons.model.dto.PageRequest;
import com.xuecheng.commons.model.vo.AuthInfo;
import com.xuecheng.commons.model.vo.PageResponseResult;
import com.xuecheng.commons.model.vo.ResponseResult;
import com.xuecheng.commons.model.vo.TeachplanVo;
import com.xuecheng.commons.utils.AuthInfoHolder;
import com.xuecheng.commons.utils.BeanHelper;
import com.xuecheng.content.config.MinioConfig;
import com.xuecheng.content.config.MinioProperties;
import com.xuecheng.content.domain.CourseBase;
import com.xuecheng.content.domain.Teachplan;
import com.xuecheng.content.mappers.CourseBaseMapper;
import com.xuecheng.content.mappers.TeachplanMapper;
import com.xuecheng.content.service.CourseBaseService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuecheng.content.service.TeachplanService;
import com.xuecheng.web.exception.BusinessException;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.errors.*;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 课程基本信息 服务实现类
 * </p>
 *
 * @author itheima
 * @since 2022-07-16
 */
@Service
public class CourseBaseServiceImpl extends ServiceImpl<CourseBaseMapper, CourseBase> implements CourseBaseService {

    @Autowired
    private MinioProperties minioProperties;

    @Autowired
    private MinioClient minioClient;

    @Autowired
    private TeachplanService teachplanService;


    //分页查询
    public ResponseResult courseList(PageRequest request, CourseDto dto) {
        //创建分页参数
        Page<CourseBase> page = new Page<>(request.getPageNo(),request.getPageSize());
        //创建查询条件
        LambdaQueryWrapper<CourseBase> qw =new LambdaQueryWrapper<>();
        //课程名称
        String courseName = dto.getCourseName();
        if (!StringUtils.isEmpty(courseName)){
            qw.like(CourseBase::getName,courseName);
        }
        //课程状态
        String status = dto.getAuditStatus();
        if (!StringUtils.isEmpty(status)){
            qw.eq(CourseBase::getAuditStatus,status);
        }
        //课程类型
        String teachmode = dto.getTeachmode();
        if (!StringUtils.isEmpty(teachmode)){
            qw.eq(CourseBase::getTeachmode,teachmode);
        }
        //设置id
        qw.eq(CourseBase::getCompanyId, AuthInfoHolder.getCompanyId());
        //分页查询
        IPage<CourseBase> iPage = this.page(page, qw);
        //转化R
        return PageResponseResult.okResult(iPage.getTotal(),iPage.getRecords());

    }

    //上传图片
    @Override
    public ResponseResult upload(MultipartFile uploadFile) throws Exception {
        InputStream stream = uploadFile.getInputStream();
        //设置上传文件的储存位置和名称   /images/2022/07/18/uuid +filename
        String filepath = "/images/"+new SimpleDateFormat("yyyy/MM/dd/")
                .format(new Date()) +
                UUID.randomUUID().toString()+uploadFile.getOriginalFilename();
        //构造请求参数
        PutObjectArgs objectArgs = PutObjectArgs.builder()
                .contentType("image/jpg") //文件类型
                .stream(stream,stream.available(), -1) //文件流
                .bucket(minioProperties.getBucket()) //存储空间
                .object(filepath) //文件
                .build();
        //发送请求
        minioClient.putObject(objectArgs);
        //构造返回
        String urlPath = minioProperties.getDomain() +"/" +
                minioProperties.getBucket() + filepath;
        return ResponseResult.okResult(urlPath);
    }

    //保存课程
    @Override
    public ResponseResult saveCourseBase(CourseBaseDto dto) {
        //验证数据的格式
        //转化对象
        CourseBase courseBase = BeanHelper.copyProperties(dto, CourseBase.class);
        //设置数据库字段
        courseBase.setCompanyName(AuthInfoHolder.getAuthInfo().getCompanyName());
        courseBase.setAuditStatus(CourseConstants.AUDIT_UNPAST_STATUS); //课程审核状态
        courseBase.setStatus(CommonConstants.USING_FLAG);     //课程删除状态
        courseBase.setCreateDate(new Date());  //添加日期
        courseBase.setPlanNum(0);    //默认章节0
        //保存
        boolean b = this.save(courseBase);
        if (!b){
            throw new BusinessException(ErrorCode.ADDEERROR);
        }
        //初始化课程大纲
        Teachplan teachplan = new Teachplan();
        teachplan.setPname(courseBase.getName());
        teachplan.setParentid(0L);
        teachplan.setGrade(CourseConstants.FIRST_LEVEL);
        teachplan.setCourseId(courseBase.getId());
        teachplan.setStatus(CommonConstants.USING_FLAG);
        teachplan.setCreateDate(new Date());
        teachplanService.save(teachplan);
        //返回
        Map map =new HashMap();
        map.put("courseBaseId",courseBase.getId());
        return ResponseResult.okResult(map);
    }

    //修改课程
    @Override
    public ResponseResult updateCourseBase(CourseBaseDto dto) {
        //验证数据格式
        //根据id查询课程数据
        CourseBase courseBase = this.getById(dto.getId());
        if (courseBase==null){
            throw new BusinessException(ErrorCode.DATAERROR);
        }

        //判断课程状态,是否可以修改
        String auditStatus = courseBase.getAuditStatus();
        if (!CourseConstants.AUDIT_DISPAST_STATUS.equals(auditStatus)&&
            !CourseConstants.AUDIT_UNPAST_STATUS.equals(auditStatus)){
            throw new BusinessException(ErrorCode.UPDATEEERROR);
        }
        //修改课程
        CourseBase c = BeanHelper.copyProperties(dto, CourseBase.class);
        boolean b = this.updateById(c);
        if (!b){
            throw new BusinessException(ErrorCode.ADDEERROR);
        }
        //返回
        Map map =new HashMap();
        map.put("courseBaseId",courseBase.getId());
        return ResponseResult.okResult(map);
    }

    //机构提交课程
    @Override
    public ResponseResult commit(Long courseBaseId) {
        //根据id查询课程
        CourseBase courseBase = this.getById(courseBaseId);
        if (courseBase==null){
            throw new BusinessException(ErrorCode.NOTFOUND);
        }

        //设置课程状态为提交
        courseBase.setAuditStatus(CourseConstants.AUDIT_COMMIT_STATUS);
        //更新
        boolean b = this.updateById(courseBase);
        if (!b){
            throw new BusinessException(ErrorCode.ERROR);
        }
        return ResponseResult.okResult();
    }

    //管理员审核课程
    @Override
    public ResponseResult approve(CourseAuditDto dto) {
        //根据id查询
        CourseBase courseBase = this.getById(dto.getCourseBaseId());
        if (courseBase==null){
            throw new BusinessException(ErrorCode.NOTFOUND);
        }
        //设置课程的字节
        courseBase.setAuditStatus(dto.getAuditStatus());
        //设置审核意见
        courseBase.setAuditMind(dto.getAuditMind());
        //更新
        boolean b = this.updateById(courseBase);
        if (!b){
            throw new BusinessException(ErrorCode.ERROR);
        }
        return ResponseResult.okResult();
    }


}
